﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using HYView;
using Transfer.CommonUnit;

namespace Transfer.CrossFloor
{
	public class CrossFloorCopyManager
	{
		public CrossFloorCopyManager(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_Doc = this.m_Revit.Application.ActiveUIDocument.Document;
			this.m_SourceView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			this.m_ClassificationBatchConverterData = new ClassificationBatchConverterData(this.m_Doc);
			string pathName = this.m_Revit.Application.ActiveUIDocument.Document.PathName;
			ElementId id = this.m_Revit.Application.ActiveUIDocument.ActiveView.Id;
			this.m_SelectionSetManager = new SelectionSetManager(pathName, id);
		}

		public Result Copy(ref string msg)
		{
			string text = "";
			if (this.m_SelectionSetManager.FileIsNotSaved() && !this.SaveNewFile())
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			List<ViewPlan> list;
			for (;;)
			{
				this.m_SelectionSetManager.ReadInfoFromFile(this.m_Doc);
				List<Element> elements = new List<Element>();
				if (!this.SelectElementSet(ref elements, ref text))
				{
					break;
				}
				this.m_SelectionSetManager.WriteInfoToFile();
				if (!this.FilterTransformElements(elements, ref text))
				{
					return Autodesk.Revit.UI.Result.Cancelled;
				}
				list = new List<ViewPlan>();
				if (this.SelectDestinationFloor(ref list))
				{
					goto Block_5;
				}
			}
			return Autodesk.Revit.UI.Result.Cancelled;
			Block_5:
			List<List<ElementId>> generalElements = new List<List<ElementId>>();
			this.m_ClassificationBatchConverterData.GetGeneralElementsIdList(ref generalElements);
			foreach (Autodesk.Revit.DB.View view in list)
			{
				Transform transform = RevitVersionFuncs.CreateTranslation(new XYZ(0.0, 0.0, view.GenLevel.Elevation - this.m_SourceView.GenLevel.Elevation));
				AutoCopyEntitiesManager autoCopyEntitiesManager = new AutoCopyEntitiesManager(this.m_Revit);
				bool copyWindows = this.FindCopyTypeByName("Windows") || this.FindCopyTypeByName("窗");
				bool copyDoors = this.FindCopyTypeByName("Doors") || this.FindCopyTypeByName("门");
				bool copyOpenings = this.FindCopyTypeByName("Rectangular Straight Wall Opening") || this.FindCopyTypeByName("矩形直墙洞口") || this.FindCopyTypeByName("Rectangular Arc Wall Opening") || this.FindCopyTypeByName("矩形弧墙洞口");
				autoCopyEntitiesManager.Copy(view, Transform.Identity, generalElements, copyWindows, copyDoors, copyOpenings);
				new ManualCopyEntitiesManager(this.m_Revit, view, transform).Copy(this.m_ClassificationBatchConverterData.AttachedToWallOfFamilyInstances, this.m_ClassificationBatchConverterData.AttachedToCeilingOfFamilyInstances, this.m_ClassificationBatchConverterData.AttachedToSurfaceOfFamilyInstances);
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private bool SelectElementSet(ref List<Element> selectElements, ref string message)
		{
			TransformTypeForm transformTypeForm;
			for (;;)
			{
				transformTypeForm = new TransformTypeForm(this.m_Revit, this.m_SelectionSetManager);
				if (transformTypeForm.ShowDialog() != DialogResult.OK)
				{
					break;
				}
				if (transformTypeForm.DialogResultIsSelecteElement)
				{
					try
					{
						List<Element> list = new List<Element>();
						if (!this.SelelctElements(ref list, ref message))
						{
							continue;
						}
						List<ComponentType> typeList = this.GetTypeList(list);
						List<ElementId> list2 = new List<ElementId>();
						foreach (Element element in list)
						{
							list2.Add(element.Id);
						}
						SelectionSet selSet = new SelectionSet("选择集", list2, typeList);
						this.m_SelectionSetManager.AddSelectionSet(selSet);
						continue;
					}
					catch (Exception)
					{
						return false;
					}
					goto IL_AA;
				}
				goto IL_AA;
			}
			return false;
			IL_AA:
			selectElements = transformTypeForm.SelectElements();
			this.m_SelectTypeList = transformTypeForm.SelectedTypeList();
			this.m_Tolerance = transformTypeForm.Tolerance();
			return true;
		}

		private bool SaveNewFile()
		{
			DialogResult dialogResult = MessageBox.Show("当前文件尚未保存，保存之后方可使用此命令，是否保存？", "盈建科提示", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
			if (DialogResult.Yes == dialogResult)
			{
				SaveFileDialog saveFileDialog = new SaveFileDialog();
				saveFileDialog.Filter = "Revit文件|*.rvt";
				saveFileDialog.RestoreDirectory = true;
				saveFileDialog.FilterIndex = 1;
				if (saveFileDialog.ShowDialog() == DialogResult.OK)
				{
					string fileName = saveFileDialog.FileName;
					SaveAsOptions saveAsOptions = new SaveAsOptions();
					saveAsOptions.OverwriteExistingFile = true;
					RevitVersionFuncs.SaveAs(this.m_Revit.Application.ActiveUIDocument.Document, fileName, saveAsOptions);
					this.m_SelectionSetManager.SetDocumentPathName(fileName);
					return true;
				}
			}
			return false;
		}

		private bool SelelctElements(ref List<Element> elements, ref string message)
		{
			Transaction transaction = null;
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			double elevation = this.m_SourceView.GenLevel.Elevation;
			transaction = new Transaction(document);
			transaction.Start("SelelctElements");
			try
			{
				IList<Reference> list = this.m_Revit.Application.ActiveUIDocument.Selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1);
				for (int i = 0; i < list.Count; i++)
				{
					Element element = document.GetElement(list[i]);
					if (element.GetType() == typeof(RoomTag) || element.GetType() == typeof(SpaceTag) || element.GetType() == typeof(AreaTag) || element.GetType() == typeof(IndependentTag))
					{
						elements.Add(element);
					}
					else if (element.Category.Id.IntegerValue == -2000260)
					{
						elements.Add(element);
					}
					else if (!(element.GetType() == typeof(Autodesk.Revit.DB.Group)))
					{
						elements.Add(element);
					}
				}
			}
			catch (Exception)
			{
				if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
				{
					transaction.RollBack();
				}
				return false;
			}
			transaction.Commit();
			return true;
		}

		private List<ComponentType> GetTypeList(List<Element> elements)
		{
			List<ComponentType> list = new List<ComponentType>();
			foreach (Element element in elements)
			{
				string name = element.GetType().Name;
				string name2 = element.Category.Name;
				ComponentType componentType = new ComponentType(name, name2);
				if (list.FindIndex((ComponentType t) => t.IsEquals(componentType)) < 0)
				{
					list.Add(componentType);
				}
			}
			return list;
		}

		private bool FilterTransformElements(List<Element> elements, ref string message)
		{
			try
			{
				for (int i = 0; i < elements.Count; i++)
				{
					Element element = elements[i];
					if (this.IsValidType(element))
					{
						if (element.GetType() == typeof(FamilyInstance))
						{
							FamilyInstance familyInstance = element as FamilyInstance;
							if (familyInstance.Category.Id.IntegerValue == -2000023 || familyInstance.Category.Id.IntegerValue == -2000014)
							{
								if (!this.IsTransformWall())
								{
									this.m_ClassificationBatchConverterData.DoorsWindowsId.Add(element.Id);
								}
							}
							else
							{
								Parameter parameter = familyInstance.Symbol.Family.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR);
								if (parameter != null)
								{
									int num = parameter.AsInteger();
									if (num == 0)
									{
										this.m_ClassificationBatchConverterData.GeneralFamilyInstancesId.Add(element.Id);
									}
									else if (num == 1)
									{
										this.m_ClassificationBatchConverterData.AttachedToWallOfFamilyInstances.Add(familyInstance);
									}
									else if (num == 3)
									{
										this.m_ClassificationBatchConverterData.AttachedToCeilingOfFamilyInstances.Add(familyInstance);
									}
									else if (num == 5)
									{
										this.m_ClassificationBatchConverterData.AttachedToSurfaceOfFamilyInstances.Add(familyInstance);
									}
									else
									{
										this.m_ClassificationBatchConverterData.GeneralFamilyInstancesId.Add(element.Id);
									}
								}
							}
						}
						else
						{
							this.FilterNonFamilyInstance(element);
						}
					}
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool FilterNonFamilyInstance(Element currentElement)
		{
			if (currentElement.GetType() == typeof(Railing))
			{
				this.m_ClassificationBatchConverterData.RailingGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Stairs))
			{
				this.m_ClassificationBatchConverterData.StairsGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Dimension))
			{
				this.m_ClassificationBatchConverterData.DimensionsId.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Autodesk.Revit.DB.Group))
			{
				this.m_ClassificationBatchConverterData.GroupGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(RevitLinkInstance))
			{
				this.m_ClassificationBatchConverterData.RevitLinkInstanceGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Opening))
			{
				this.m_ClassificationBatchConverterData.OpeningGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(TextNote))
			{
				this.m_ClassificationBatchConverterData.TextNoteGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Wall))
			{
				this.m_ClassificationBatchConverterData.WallGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Ceiling))
			{
				this.m_ClassificationBatchConverterData.CeilingGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Floor))
			{
				this.m_ClassificationBatchConverterData.FloorGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Room) || currentElement.GetType() == typeof(Space) || currentElement.GetType() == typeof(Zone) || currentElement.GetType() == typeof(Area))
			{
				this.m_ClassificationBatchConverterData.RoomsSpacesZonesAreasId.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(RoomTag) || currentElement.GetType() == typeof(SpaceTag) || currentElement.GetType() == typeof(AreaTag) || currentElement.GetType() == typeof(IndependentTag))
			{
				this.m_ClassificationBatchConverterData.TagId.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Pipe))
			{
				this.m_ClassificationBatchConverterData.PipeGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(FlexPipe))
			{
				this.m_ClassificationBatchConverterData.FlexPipeGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Duct))
			{
				this.m_ClassificationBatchConverterData.DuctGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(FlexDuct))
			{
				this.m_ClassificationBatchConverterData.FlexDuctGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(CableTray))
			{
				this.m_ClassificationBatchConverterData.CableTrayGeneralElementsIdList.Add(currentElement.Id);
			}
			else if (currentElement.GetType() == typeof(Conduit))
			{
				this.m_ClassificationBatchConverterData.ConduitGeneralElementsIdList.Add(currentElement.Id);
			}
			else
			{
				if (!(currentElement.GetType() == typeof(Wire)))
				{
					return false;
				}
				this.m_ClassificationBatchConverterData.WiresList.Add(currentElement.Id);
			}
			return true;
		}

		private bool IsTransformWall()
		{
			using (List<ComponentType>.Enumerator enumerator = this.m_SelectTypeList.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.m_Type.CompareTo("Wall") == 0)
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool IsValidType(Element element)
		{
			string name = element.GetType().Name;
			string name2 = element.Category.Name;
			ComponentType componentType = new ComponentType(name, name2);
			return this.m_SelectTypeList.FindIndex((ComponentType t) => t.IsEquals(componentType)) >= 0;
		}

		private bool FindCopyTypeByName(string findName)
		{
			return this.m_SelectTypeList.FindIndex((ComponentType t) => t.m_Category.CompareTo(findName) == 0) >= 0;
		}

		private bool SelectDestinationFloor(ref List<ViewPlan> selectedViews)
		{
			return FloorSelectManager.SelectFloorViewPlans(this.m_Doc, ref selectedViews, null);
		}

		private ExternalCommandData m_Revit;

		private Document m_Doc;

		private Autodesk.Revit.DB.View m_SourceView;

		private ClassificationBatchConverterData m_ClassificationBatchConverterData;

		private List<ComponentType> m_SelectTypeList = new List<ComponentType>();

		private SelectionSetManager m_SelectionSetManager;

		private double m_Tolerance;
	}
}
